home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Plus
/
Graphics Plus.iso
/
amiga
/
viewers
/
ham8_jpg.lha
/
ham8-jpeg
/
Source
/
al-j.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-12-20
|
13KB
|
570 lines
/*
* Al-j.c Michael Saunby M.Saunby@reading.ac.uk
*
* Release 1.1 December 1992 Jpeg viewer using Albert HAM8 public screen and
* Independent JPEG groups jpeg decompressor.
*/
#define PROG_NAME "Al-J JPEG Viewer"
#define COPYRIGHT_MESSAGE "Version 1.1\nDecember 1992\n\nCopyright ⌐ 1992\n\
Michael Saunby\n\
\nThis program is based in part\n\
on the work of the Independent\n\
JPEG Group"
#include <intuition/intuition.h>
#include <intuition/gadgetclass.h>
#include <graphics/gfxbase.h>
#include <graphics/displayinfo.h>
#include <intuition/screens.h>
#include <dos/dosextens.h>
#include <dos/dosasl.h>
#include <libraries/gadtools.h>
#include <clib/asl_protos.h>
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/layers_protos.h>
#include <clib/graphics_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/dos_protos.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "display24.h"
/* Values greater than 1 give bad pixels, why? */
#define ARRAY24_MAX_ROWS 1
/*
* ReadArgs() template
*/
#define TEMPLATE "NAME"
#define OPT_NAME 0
#define OPT_COUNT 1
int JPEG_restart = 0; /* set to 1 for New file */
struct IntuitionBase *IntuitionBase = NULL;
struct GfxBase *GfxBase = NULL;
struct Library *GadToolsBase = NULL;
struct Library *AslBase = NULL;
extern struct ExecBase *SysBase;
/* following for 24 bit put row */
SHORT ham8_line; /* screen line number to draw at */
UBYTE *ham8_pens = NULL;
struct RastPort ham8_temprp;
struct BitMap *temp_bm = NULL;
struct Screen *screen = NULL;
struct FileRequester *filereq = NULL;
struct BitMap *bitmap = NULL;
struct Window *window = NULL;
struct Menu *menu;
struct Gadget *gadgets, *horprop = NULL, *vertprop = NULL;
void *vi;
ULONG allocsignal;
/* gadget ids */
#define HORPROP 1
#define VERTPROP 2
/* current x and y offsets */
LONG scroll_x = 0;
LONG scroll_y = 0;
LONG window_max_w;
LONG window_max_h;
struct EasyStruct failedES =
{sizeof (struct EasyStruct), 0, PROG_NAME,
"%s", "OK",};
#define OPEN 1
#define ABOUT 2
#define QUIT 3
struct NewMenu prj_menu[] =
{
{NM_TITLE, "Project", 0, 0, 0, 0,},
{NM_ITEM, "Open...", "O", 0, 0, (void *) OPEN,},
{NM_ITEM, NM_BARLABEL, 0, 0, 0, 0,},
{NM_ITEM, "About...", "?", 0, 0, (void *) ABOUT,},
{NM_ITEM, "Quit", "Q", 0, 0, (void *) QUIT,},
{NM_END, NULL, 0, 0, 0, 0,},
};
void
Cleanup ()
{
if (screen)
UnlockPubScreen (NULL, screen);
screen = NULL;
if (window)
{
ReleasePens (&(window->WScreen->ViewPort));
FreeVisualInfo (vi);
CloseWindow (window);
gadgets = NULL;
}
window = NULL;
if (menu)
ClearMenuStrip (window);
menu = NULL;
if (horprop)
DisposeObject (horprop);
horprop = NULL;
if (vertprop)
DisposeObject (vertprop);
vertprop = NULL;
if (ham8_pens)
FreeMem (ham8_pens, ((temp_bm->BytesPerRow << 3) * temp_bm->Rows));
ham8_pens = NULL;
if (temp_bm)
FreeBitMap (temp_bm);
temp_bm = NULL;
if (bitmap)
FreeBitMap (bitmap);
bitmap = NULL;
if (!JPEG_restart)
{
if (filereq)
FreeAslRequest (filereq);
filereq = NULL;
if (AslBase)
CloseLibrary (AslBase);
AslBase = NULL;
if (GadToolsBase)
CloseLibrary (GadToolsBase);
GadToolsBase = NULL;
if (IntuitionBase)
CloseLibrary ((struct Library *) IntuitionBase);
IntuitionBase = NULL;
if (GfxBase)
CloseLibrary ((struct Library *) GfxBase);
GfxBase = NULL;
}
}
void
Quit (char whytext[], UBYTE failcode)
{
EasyRequest (NULL, &failedES, NULL, whytext);
Cleanup ();
exit (failcode);
}
void
UserWait ()
{
struct IntuiMessage *msg;
struct Gadget *gadget;
BOOL abort = FALSE;
UWORD class, code;
LONG new_x, new_y;
SetGadgetAttrs (horprop, window, NULL,
GA_Disabled, FALSE,
TAG_END);
SetGadgetAttrs (vertprop, window, NULL,
GA_Disabled, FALSE,
TAG_END);
do
{
WaitPort (window->UserPort);
while (msg = GT_GetIMsg (window->UserPort))
{
code = msg->Code;
class = msg->Class;
gadget = (struct Gadget *) msg->IAddress;
GT_ReplyIMsg (msg);
switch (class)
{
case IDCMP_MENUPICK:
switch ((UWORD) MENU_USERDATA (ItemAddress (menu, code)))
{
case QUIT:
abort = TRUE;
break;
case OPEN:
JPEG_restart = TRUE;
abort = TRUE;
break;
case ABOUT:
EasyRequest (window, &failedES,
NULL,
COPYRIGHT_MESSAGE);
break;
}
break;
case IDCMP_CLOSEWINDOW:
abort = TRUE;
break;
case IDCMP_SIZEVERIFY:
case IDCMP_NEWSIZE:
SetGadgetAttrs (vertprop, window, NULL,
PGA_Visible, window->GZZHeight,
TAG_END);
SetGadgetAttrs (horprop, window, NULL,
PGA_Visible, window->GZZWidth,
TAG_END);
break;
case IDCMP_GADGETUP:
switch (gadget->GadgetID)
{
case HORPROP:
GetAttr (PGA_Top, horprop, &new_x);
ScrollLayer (0L, window->RPort->Layer, new_x - scroll_x, 0);
scroll_x = new_x;
WindowLimits (window, 0, 0, window_max_w - scroll_x, 0);
break;
case VERTPROP:
GetAttr (PGA_Top, vertprop, &new_y);
ScrollLayer (0L, window->RPort->Layer, 0, new_y - scroll_y);
scroll_y = new_y;
WindowLimits (window, 0, 0, 0, window_max_h - scroll_y);
break;
}
break;
default:
/*
* EasyRequest(window, &failedES, NULL, "Bogus message
* sorry!");
*/
break;
}
}
} while (abort == FALSE);
Cleanup ();
}
char *
Startup (char *namebuf)
{
char *ret_code = NULL;
LONG result[OPT_COUNT] =
{0};
struct RDArgs *rda;
if (!JPEG_restart)
{
if ((GfxBase =
(struct GfxBase *) OpenLibrary ("graphics.library", 36)) == NULL)
Quit ("graphics.library is too old <V36", 25);
if ((IntuitionBase =
(struct IntuitionBase *) OpenLibrary ("intuition.library", 36)) == NULL)
Quit ("intuition.library is too old <V36", 25);
if ((AslBase = OpenLibrary ("asl.library", 36)) == NULL)
Quit ("asl.library is too old <V36", 25);
if ((GadToolsBase = OpenLibrary ("gadtools.library", 36)) == NULL)
Quit ("gadtools.library is too old <V36", 25);
if ((filereq =
(struct FileRequester *) AllocAslRequestTags (ASL_FileRequest,
ASLFR_PubScreenName, HAM8_ALBERT_NAME,
TAG_END))
== NULL)
Quit ("could not build file requster", 25);
rda = ReadArgs (TEMPLATE, result, NULL);
if (result[OPT_NAME])
{
strcpy (namebuf, (UBYTE *) result[OPT_NAME]);
ret_code = namebuf;
}
FreeArgs (rda);
}
JPEG_restart = FALSE;
if (ret_code == NULL)
{
struct Screen *screen;
/*
* Opening the File Requester does not bring screen to front. Passing
* the name ie. UnlockPubscreen(HAM8_ALBERT_NAME, NULL) is allowed
* but not recommended. I haven't tried it.
*/
if ((screen = LockPubScreen (HAM8_ALBERT_NAME)) != NULL)
{
ScreenToFront (screen);
UnlockPubScreen (NULL, screen);
}
if (AslRequest (filereq, 0L))
{
if(filereq->rf_Dir[strlen(filereq->rf_Dir)-1] == ':')
sprintf (namebuf, "%s%s", filereq->rf_Dir, filereq->rf_File);
else
sprintf (namebuf, "%s/%s", filereq->rf_Dir, filereq->rf_File);
ret_code = namebuf;
}
}
ham8_line = 0;
return (ret_code);
}
void
CreateWindow (UWORD width, UWORD height)
{
int pen_errors;
struct Gadget **tmpgad;
if ((menu = CreateMenus (prj_menu, GTMN_FrontPen, 1, TAG_DONE)) == NULL)
Quit ("could not build menu", 25);
if ((screen = LockPubScreen (HAM8_ALBERT_NAME)) == NULL)
Quit ("could not find screen", 25);
if ((bitmap = AllocBitMap (width, height, 8, BMF_DISPLAYABLE | BMF_CLEAR,
NULL)) == NULL)
Quit ("could not allocate bitmap", 25);
gadgets = NULL;
tmpgad = &gadgets;
/* Create scroller gadgets */
horprop = (struct Gadget *) NewObject (NULL, "propgclass",
GA_Immediate, TRUE,
GA_BottomBorder, TRUE,
GA_GZZGadget, TRUE,
GA_RelVerify, TRUE,
PGA_Freedom, FREEHORIZ,
PGA_Borderless, FALSE,
PGA_NewLook, TRUE,
GA_RelBottom, -10,
GA_RelWidth, -21,
GA_Left, 3,
GA_Height, 7,
PGA_Top, 0,
PGA_Visible, width,
PGA_Total, width,
GA_ID, HORPROP,
GA_Previous, tmpgad,
TAG_END);
vertprop = (struct Gadget *) NewObject (NULL, "propgclass",
GA_Immediate, TRUE,
GA_RightBorder, TRUE,
GA_GZZGadget, TRUE,
GA_RelVerify, TRUE,
PGA_Freedom, FREEVERT,
PGA_Borderless, FALSE,
PGA_NewLook, TRUE,
GA_RelHeight, -21,
GA_RelRight, -13,
GA_Width, 10,
GA_Top, 10,
PGA_Top, 0,
PGA_Visible, height,
PGA_Total, height,
GA_ID, VERTPROP,
GA_Previous, tmpgad,
TAG_END);
if ((window = OpenWindowTags (NULL,
WA_Title, PROG_NAME,
WA_Top, screen->BarHeight + 1,
WA_InnerHeight, height,
WA_InnerWidth, width,
WA_NewLookMenus, TRUE,
WA_PubScreen, screen,
WA_SizeGadget, TRUE,
WA_DepthGadget, TRUE,
WA_DragBar, TRUE,
WA_CloseGadget, TRUE,
WA_Activate, FALSE,
WA_SizeBBottom, TRUE,
WA_SizeBRight, TRUE,
WA_MinWidth, 64,
WA_MinHeight, 32,
WA_MaxWidth, -1,
WA_MaxHeight, -1,
WA_AutoAdjust, TRUE,
WA_SuperBitMap, bitmap,
WA_GimmeZeroZero, TRUE,
WA_Gadgets, gadgets,
WA_IDCMP, MENUPICK | IDCMP_NEWSIZE |
IDCMP_SIZEVERIFY | CLOSEWINDOW | GADGETUP,
TAG_END)) == NULL)
{
Quit ("could not open window\nProbably not enough chip ram", 25);
}
vi = GetVisualInfo (screen, TAG_END);
/*
* Have window now so no longer need lock on screen.
*/
UnlockPubScreen (NULL, screen);
screen = NULL;
if (LayoutMenus (menu, vi, TAG_DONE) == NULL)
Quit ("could not layout menu", 25);
SetMenuStrip (window, menu);
/*
* The window may not have opened at the size we asked for so fix the
* prop gads.
*/
SetGadgetAttrs (horprop, window, NULL,
PGA_Visible, window->GZZWidth,
PGA_Top, 0,
GA_Disabled, TRUE,
TAG_END);
SetGadgetAttrs (vertprop, window, NULL,
PGA_Visible, window->GZZHeight,
PGA_Top, 0,
GA_Disabled, TRUE,
TAG_END);
window_max_w = window->Width;
window_max_h = window->Height;
scroll_x = 0;
scroll_y = 0;
WindowLimits (window, 0, 0, window_max_w, window_max_h);
CopyMem (&(window->RPort), &ham8_temprp, sizeof (struct RastPort));
ham8_temprp.Layer = NULL;
if ((temp_bm = AllocBitMap (width, /* height */ 1, /* depth */ 8, 0L, bitmap)) == NULL)
Quit ("cannot get line bitmap", 25);
ham8_temprp.BitMap = temp_bm;
ham8_pens = AllocMem (((temp_bm->BytesPerRow << 3) * ARRAY24_MAX_ROWS), 0L);
/*
* Get a copy of the special palette. The palette is set when the screen
* is created.
*/
pen_errors = StandardPalette (&(window->WScreen->ViewPort), TRUE);
if (pen_errors)
EasyRequest (window, &failedES,
NULL,
"Could not find full HAM-8 Albert palette");
}
#undef GLOBAL /* Means something else to IJPEG code */
#include "jinclude.h"
#ifndef EIGHT_BIT_SAMPLES
Sorry, this code only copes with 8 - bit JSAMPLEs. /* deliberate syntax err */
#endif
/*
* Write the file header.
*/
METHODDEF void
output_init (decompress_info_ptr cinfo)
{
CreateWindow ((SHORT) cinfo->image_width, (SHORT) cinfo->image_height);
}
/*
* Write some pixel data.
*/
METHODDEF void
put_pixel_rows (decompress_info_ptr cinfo, int num_rows,
JSAMPIMAGE pixel_data)
{
JSAMPROW ptr0, ptr1, ptr2;
long width = cinfo->image_width;
int row, height;
for (row = 0; row < num_rows; row += height)
{
ptr0 = pixel_data[0][row];
ptr1 = pixel_data[1][row];
ptr2 = pixel_data[2][row];
height = num_rows - row; /* ie rows left */
height = (ARRAY24_MAX_ROWS < height) ? ARRAY24_MAX_ROWS : height;
WritePixelArray24 (window->RPort, 0, ham8_line,
width, height,
ptr0, ptr1, ptr2, ham8_pens, &ham8_temprp);
ham8_line += height;
}
}
METHODDEF void
put_gray_rows (decompress_info_ptr cinfo, int num_rows,
JSAMPIMAGE pixel_data)
{
JSAMPROW ptr0;
long width = cinfo->image_width;
int row, height;
for (row = 0; row < num_rows; row += height)
{
ptr0 = pixel_data[0][row];
height = num_rows - row; /* ie rows left */
height = (ARRAY24_MAX_ROWS < height) ? ARRAY24_MAX_ROWS : height;
/* Dont have a special grayscale function yet */
WritePixelArray24 (window->RPort, 0, ham8_line,
width, height,
ptr0, ptr0, ptr0, ham8_pens, &ham8_temprp);
ham8_line += height;
}
}
/*
* Might be nice to try quantized output sometime.
*/
METHODDEF void
put_demapped_rows (decompress_info_ptr cinfo, int num_rows,
JSAMPIMAGE pixel_data)
{
}
METHODDEF void
put_color_map (decompress_info_ptr cinfo, int num_colors, JSAMPARRAY colormap)
{
}
/*
* Finish up at the end of the file.
*/
METHODDEF void
output_term (decompress_info_ptr cinfo)
{
UserWait ();
}
/*
* The method selection routine for HAM8 format output. This should be called
* from d_ui_method_selection if HAM8 output is wanted.
*/
GLOBAL void
jselwham8 (decompress_info_ptr cinfo)
{
cinfo->methods->output_init = output_init;
cinfo->methods->put_color_map = put_color_map;
if(cinfo->out_color_space == CS_RGB)
cinfo->methods->put_pixel_rows = put_pixel_rows;
else
cinfo->methods->put_pixel_rows = put_gray_rows;
cinfo->methods->output_term = output_term;
}